package com.lcredu.aop.aspectj;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * @author 黎长容
 * @date 2025-07-15 15:27
 * 这是一个切面类
 */
@Order(value = 2)
@Aspect
@Component
public class SmartAnimalAspect2 {

    //定义一个切入点表达式重用
    @Pointcut(value = "execution(public int com.lcredu.aop.aspectj.SmartDog.getSum(int,int ))")
    public void myPointCut(){
        
    }
    
//    @Around(value = "execution(public int SmartDog.getSum(int, int))")
//    public Object doAround(ProceedingJoinPoint joinPoint) {
//        Object result = null;
//        String methodName = joinPoint.getSignature().getName();
//        try {
////1.相当于前置通知完成的事情
//            Object[] args = joinPoint.getArgs();
//            List<Object> argList = Arrays.asList(args);
//            System.out.println("AOP 环绕通知--" + methodName + "方法开始了--参数有： " + argList);
////在环绕通知中一定要调用 joinPoint.proceed()来执行目标方法
//            result = joinPoint.proceed();
////2.相当于返回通知完成的事情
//            System.out.println("AOP 环绕通知" + methodName + "方法结束了--结果是：" + result);
//        } catch (Throwable throwable) {
////3.相当于异常通知完成的事情
//            System.out.println("AOP 环绕通知" + methodName + "方法抛异常了--异常对 象：" + throwable);
//        } finally {
////4.相当于最终通知完成的事情
//            System.out.println("AOP 后置通知" + methodName + "方法最终结束了...");
//        }
//        return result;
//    }

    //写一个前置通知,作用于public int getSum(int num1, int num2)
//    @Before(value = "execution(public int com.lcredu.aop.aspectj.SmartDog.getSum(int, int))")
    @Before(value = "myPointCut()")
    public void before(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        System.out.println("myPointCut切入点表达式重用--SmartAnimalAspect---before--前置通知---日志-方法名-" + signature.getName() + "-参数" + Arrays.asList(joinPoint.getArgs()));
    }

    //后置通知
    //后置通知拿到返回结果可以添加属性returning
    //细节: returning = "res" 里面的res要和Object res里的res一致
//    @AfterReturning(value = "execution(public int com.lcredu.aop.aspectj.SmartDog.getSum(int ,int ))", returning = "res")
    @AfterReturning(value = "myPointCut()",returning = "res")
    public void afterReturn(JoinPoint joinPoint, Object res) {
        Signature signature = joinPoint.getSignature();
        System.out.println("SmartAnimalAspect---after--后置通知--方法名=" + signature.getName() + "返回结果为" + res);
    }

    //异常通知
    //异常通知获取异常信息
//    @AfterThrowing(value = "execution(public int com.lcredu.aop.aspectj.SmartDog.getSum(int ,int ))", throwing = "throwable")
    @AfterThrowing(value = "myPointCut()",throwing = "throwable")
    public void yc(JoinPoint joinPoint, Throwable throwable) {
        Signature signature = joinPoint.getSignature();
        System.out.println("SmartAnimalAspect---exception--异常通知--方法名=" + signature.getName() + " 异常信息=" + throwable);
    }

    //最终通知
//    @After(value = "execution(public int com.lcredu.aop.aspectj.SmartDog.getSum(int ,int ))")
    @After(value = "myPointCut()")
    public void after(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        System.out.println("SmartAnimalAspect---after--最终通知--方法名=" + signature.getName());
    }
}
